/**
 * 每一圈做一次循环
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function (matrix) {
    let maxI = matrix.length,
        maxJ = matrix[0].length,
        curI = 0,
        count = 0,
        res = []

    while (count < maxI * maxJ) {
        // 第一行push进去
        while (matrix[curI].length > 0) {
            res.push(matrix[curI].shift())
            count++
        }
        // 往下面的行走，取每一行的最后一个值
        while (matrix[++curI]?.length > 0) {
            res.push(matrix[curI].pop())
            count++
        }
        curI--
        // 最后一行，全部pop
        while (matrix[curI].length > 0) {
            res.push(matrix[curI].pop())
            count++
        }
        // 往上走，取每一行的第一个值
        while (matrix[--curI]?.length > 0) {
            res.push(matrix[curI].shift())
            count++
        }
        curI++
        // 完成一次循环
    }

    return res
};

/**
 * 官解，循环
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function (matrix) {
    let bottom = matrix.length - 1,
        right = matrix[0].length - 1,
        left = 0,
        top = 0,
        res = []

    // 更新每圈的四个端点
    while (left <= right && top <= bottom) {
        // 上边的左上端点到右上端点
        for (let column = left; column <= right; column++) {
            res.push(matrix[top][column])
        }
        // 右边的右上端点下一行到右下端点
        for (let row = top + 1; row <= bottom; row++) {
            res.push(matrix[row][right])
        }
        // 如果目前的这次循环是多行且多列
        if (left < right && top < bottom) {
            // 右边的右下端点的左一列到左下端点
            for (let column = right - 1; column >= left; column--) {
                res.push(matrix[bottom][column])
            }
            // 左下端点上一行到左上端点下一行
            for (let row = bottom - 1; row > top; row--) {
                res.push(matrix[row][left])
            }
        }
        // 更新四个端点
        [left, top, right, bottom] = [left + 1, top + 1, right - 1, bottom - 1]
    }

    return res
};
